'''
Created on 25 Oct 2012

@author: quirino.brizi
'''
from org.codesketch.loadit.decorator import accepts

@accepts(str, str)
def instance(module, clazz):
    '''
    Dynamically load an instance of the requested class from the given module
    @param module: the module where the class is defined
    @param clazz: the class name
    @return: an instance of clazz loaded from module
    '''
    # import the module
    mod = __import__(module)
    # load module components
    for comp in module.split('.')[1:] : mod = getattr(mod, comp)
    # instantiate and return the class
    return getattr(mod, clazz)()

@accepts(str, str)
def load(path, opt='r'):
    '''
    Attempt open the requested file directly or looking up on classpath
    @param path: the base path
    @param opt: the opening option as defined on built in apen() method
    '''
    try :
        return open(path, opt)
    except IOError :
        from sys import path as _classpath
        for p in _classpath :
            try : return open('%s/%s' % (p, path), opt) 
            except : continue

@accepts(dict)
def generateParametersCombination(params={}):
    '''
    Generate all the possible combination in a random order of the parameters 
    provided using the params argument.
    @param params: the map that contains the parameters key value pairs
    @return: a list containing all the possible parameters combinations as a dictionary
    '''
    comb = []
    keys = params.keys()
    size = len(keys)
    for k in range(size) :
        key = keys[k]
        for value in params[key] : comb.append({key:value})
#            comb.append("%s=%s" % (key, value))
        if k > 0 :
            tmp = []
            for value in params[key] :
#                cp = "%s=%s" % (key, value)
                cp = {key:value}
                for c in comb : 
                    if not key in c.keys() : 
                        tmp.append(copyAndExtendDict(cp, c))
#                    if not c.startswith(key) : tmp.append("%s&%s" % (c, cp))
            comb.extend(tmp)
    return comb

def copyAndExtendDict(base, *args):
    '''
    Create a copy and extends the given base dictionary adding the content of all the other 
    dictionaries passed as a parameter.
    '''
    ext = base.copy()
    for arg in args : ext.update(arg)
    return ext